﻿using System;
using System.Collections.Generic;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.UI;
using YArchitech.Controls;
using YArchitech.Revit;

namespace YArchitech.Plumbing.Model
{
	public class SprinklerGroup
	{
		public SprinklerGroup(List<Element> _sprinkers, UIDocument _uidoc)
		{
			try
			{
				this.sprinklers = _sprinkers;
				this.uiDoc = _uidoc;
				if (this.sprinklers.Count > 0)
				{
					ConnectorSetIterator connectorSetIterator = (this.sprinklers[0] as FamilyInstance).MEPModel.ConnectorManager.Connectors.ForwardIterator();
					connectorSetIterator.MoveNext();
					Connector connector = connectorSetIterator.Current as Connector;
					ConnectorSetIterator connectorSetIterator2 = connector.AllRefs.ForwardIterator();
					if (connectorSetIterator2.MoveNext())
					{
						connector = (connectorSetIterator2.Current as Connector);
					}
					this.allElements.Add(this.sprinklers[0]);
					SearchBranch searchBranch = new SearchBranch(new ElementNode(connector.Owner, connector));
					searchBranch.DoSearch();
					ElementNode listRoot = searchBranch.GetListRoot();
					List<ElementNode> list = new List<ElementNode>();
					list = this.GetAllElemNode(listRoot, ref list);
					foreach (ElementNode elementNode in list)
					{
						this.allElements.Add(elementNode.Element);
					}
				}
				this.mainPipes.AddRange(this.GetMainPipes());
				this.SetPosition();
				this.SetEndPoint();
				this.SetSystemLine();
			}
			catch (Exception ex)
			{
				YJKMessageBox.Show(ex.Message);
			}
		}

		private List<ElementNode> GetAllElemNode(ElementNode eNode, ref List<ElementNode> listENode)
		{
			if (eNode == null)
			{
				return listENode;
			}
			listENode.Add(eNode);
			this.GetAllElemNode(eNode.Next, ref listENode);
			if (eNode.SubElementNode != null)
			{
				foreach (ElementNode eNode2 in eNode.SubElementNode)
				{
					this.GetAllElemNode(eNode2, ref listENode);
				}
			}
			return listENode;
		}

		private List<Element> GetMainPipes()
		{
			List<Element> list = new List<Element>();
			foreach (Element element in this.allElements)
			{
				Pipe pipe = element as Pipe;
				if (pipe != null && !YJKRevitTools.isRiserPipe(pipe))
				{
					list.Add(element);
				}
			}
			return list;
		}

		public bool Move(XYZ offset)
		{
			bool result;
			try
			{
				List<ElementId> list = new List<ElementId>();
				foreach (Element element in this.allElements)
				{
					list.Add(element.Id);
				}
				ElementTransformUtils.MoveElements(this.uiDoc.Document, list, offset);
				this.uiDoc.Document.Regenerate();
				this.SetPosition();
				this.SetEndPoint();
				this.SetSystemLine();
				result = true;
			}
			catch
			{
				result = false;
			}
			return result;
		}

		public bool MovePoint(XYZ point, XYZ offset)
		{
			bool result;
			try
			{
				if (!(this.startPoint - this.endPoint).Normalize().IsAlmostEqualTo(offset.Normalize()) && !(this.endPoint - this.startPoint).Normalize().IsAlmostEqualTo(offset.Normalize()))
				{
					result = false;
				}
				else
				{
					Element element = null;
					foreach (Element element2 in this.sprinklers)
					{
						XYZ point2 = (element2.Location as LocationPoint).Point;
						if (point.DistanceTo(point2) < 0.1)
						{
							element = element2;
							break;
						}
					}
					if (element == null)
					{
						result = false;
					}
					else
					{
						ElementTransformUtils.MoveElement(this.uiDoc.Document, element.Id, offset);
						this.uiDoc.Document.Regenerate();
						this.SetPosition();
						this.SetEndPoint();
						this.SetSystemLine();
						result = true;
					}
				}
			}
			catch
			{
				result = false;
			}
			return result;
		}

		private void SetPosition()
		{
			foreach (Element element in this.sprinklers)
			{
				XYZ point = (element.Location as LocationPoint).Point;
				bool flag = true;
				using (List<XYZ>.Enumerator enumerator2 = this.sprinklerPosition.GetEnumerator())
				{
					while (enumerator2.MoveNext())
					{
						if (enumerator2.Current.DistanceTo(point) < 0.1)
						{
							flag = false;
							break;
						}
					}
				}
				if (flag)
				{
					this.sprinklerPosition.Add(point);
				}
			}
		}

		private void SetEndPoint()
		{
			double num = double.NegativeInfinity;
			if (this.sprinklerPosition.Count > 1)
			{
				foreach (XYZ xyz in this.sprinklerPosition)
				{
					foreach (XYZ xyz2 in this.sprinklerPosition)
					{
						double num2 = xyz.DistanceTo(xyz2);
						if (num2 > num)
						{
							num = num2;
							this.startPoint = xyz;
							this.endPoint = xyz2;
						}
					}
				}
			}
		}

		private void SetSystemLine()
		{
			if (this.startPoint != null && this.endPoint != null)
			{
				this.systemLine = Line.CreateBound(new XYZ(this.startPoint.X, this.startPoint.Y, 0.0), new XYZ(this.endPoint.X, this.endPoint.Y, 0.0));
			}
		}

		public List<XYZ> sprinklerPosition = new List<XYZ>();

		public List<Element> sprinklers = new List<Element>();

		public List<Element> allElements = new List<Element>();

		public List<Element> mainPipes = new List<Element>();

		public Line systemLine;

		public XYZ startPoint;

		public XYZ endPoint;

		public List<ColumnModel> conflictCMList = new List<ColumnModel>();

		public List<BeamModel> beamList = new List<BeamModel>();

		public UIDocument uiDoc;
	}
}
